package com.boby.homecamera.helper

import android.content.Context
import android.os.Handler
import android.os.HandlerThread
import android.util.Log
import com.boby.homecamera.config.AppConfig
import com.boby.homecamera.db.DBManager
import com.boby.homecamera.db.VideoEventTable.VideoEvent
import com.boby.homecamera.service.MainService
import com.boby.homecamera.util.FileUtil
import com.boby.homecamera.yolo.YOLO11Ncnn
import com.boby.lib_common.BaseApplication
import com.pedro.encoder.input.gl.render.filters.MultiBoxBorderFilterRender

class VideoDetectHelper {
    private val yolo11ncnn: YOLO11Ncnn = YOLO11Ncnn()
    private var detectPersonHandler: Handler? =null
    private val PERSON_VISIBLE_TIME = 10000
    private val PERSON_DETECT_TIME = 90
    private var isStart = false
    fun initPersonDetect(context:Context){
        isStart = true
        yolo11ncnn.loadModel(context.assets,0,0,0)

        val detectPersonHandlerThread = HandlerThread("detectPersonHandler")
        detectPersonHandlerThread.start()
        detectPersonHandler = Handler(detectPersonHandlerThread.looper)
        detectPerson()
        MainService.recordServer?.glInterface?.addFilter(multiFilter)
    }


    val multiFilter = MultiBoxBorderFilterRender()

    private var fpsCount = 0
    private var lastFpsTime = 0L
    private var lastDetectPersonTime = 0L
    private fun detectPerson(){
        if(!isStart){
            return
        }
        MainService.recordServer?.glInterface?.takePhotoByteBuffer {
            detectPersonHandler?.post {
//                val startTime = System.currentTimeMillis()
                val rotation = AppConfig.detectOrientation
                val objs =  yolo11ncnn.detectRGBABuffer( it, AppConfig.Record.CAPTURE_WIDTH, AppConfig.Record.CAPTURE_HEIGHT,rotation)
                multiFilter.clearBoxes()
                var hasPerson = false
                for (obj in objs) {
// 添加两个框
                    if(obj.label == 0){
                        if(!hasPerson){
                            hasPerson = true
                        }
                        when (rotation) {

                            90 -> { //上
                                // 旋转 90° (顺时针)
                                val cx = (obj.y + obj.h / 2f) / AppConfig.Record.CAPTURE_WIDTH
                                val cy = 1f - (obj.x + obj.w / 2f) / AppConfig.Record.CAPTURE_HEIGHT
                                val wNorm = obj.h / AppConfig.Record.CAPTURE_WIDTH
                                val hNorm = obj.w / AppConfig.Record.CAPTURE_HEIGHT

                                multiFilter.addBox(cx, cy, wNorm, hNorm, 0.002f, 0f, 1f, 0f, 1f)
                            }

                            180 -> {//左
                                // 旋转 180°
                                val cx = 1f - (obj.x + obj.w / 2f) / AppConfig.Record.CAPTURE_WIDTH
                                val cy = 1f - (obj.y + obj.h / 2f) / AppConfig.Record.CAPTURE_HEIGHT
                                val wNorm = obj.w / AppConfig.Record.CAPTURE_WIDTH
                                val hNorm = obj.h / AppConfig.Record.CAPTURE_HEIGHT

                                multiFilter.addBox(cx, cy, wNorm, hNorm, 0.002f, 0f, 1f, 0f, 1f)
                            }

                            270 -> {//下
                                // 旋转 270° (顺时针等于逆时针 90°)
                                val cx = 1f - (obj.y + obj.h / 2f) / AppConfig.Record.CAPTURE_WIDTH
                                val cy = (obj.x + obj.w / 2f) / AppConfig.Record.CAPTURE_HEIGHT
                                val wNorm = obj.h / AppConfig.Record.CAPTURE_WIDTH
                                val hNorm = obj.w / AppConfig.Record.CAPTURE_HEIGHT

                                multiFilter.addBox(cx, cy, wNorm, hNorm, 0.002f, 0f, 1f, 0f, 1f)
                            }
                            else ->  {//右
                                // 右下
                                multiFilter.addBox(
                                    (obj.x + obj.w / 2f) / AppConfig.Record.CAPTURE_WIDTH,
                                    (obj.y + obj.h / 2f) / AppConfig.Record.CAPTURE_HEIGHT,
                                    obj.w / AppConfig.Record.CAPTURE_WIDTH,
                                    obj.h / AppConfig.Record.CAPTURE_HEIGHT,
                                    0.002f, 0f, 1f, 0f, 1f
                                )
                            }
                        }


                    }

                }
                if(System.currentTimeMillis() - lastFpsTime > 1000){
//                    Log.d("YOLO", "FPS:${fpsCount}")
                    fpsCount = 0
                    lastFpsTime = System.currentTimeMillis()

                }
                fpsCount ++
                saveVideoEvent(hasPerson)
                val currentTime = System.currentTimeMillis()
                val delayTime = PERSON_DETECT_TIME - (currentTime - lastDetectPersonTime)
                lastDetectPersonTime = currentTime
                if(delayTime > 0){
                    detectPersonHandler?.postDelayed({
                        detectPerson()
                    },delayTime)
                }else{
                    detectPerson()
                }

            }

        }?:{
            detectPersonHandler?.postDelayed({
                detectPerson()
            },1000)
        }
    }



    private var lastVideoEvent: VideoEvent? = null
    private fun saveVideoEvent(hasPerson: Boolean){
        if(hasPerson){//检测到人像
            val startTime = System.currentTimeMillis()
            if(lastVideoEvent != null){
                if(startTime > lastVideoEvent!!.endTime ){
                    lastVideoEvent!!.endTime = startTime + PERSON_VISIBLE_TIME
                    DBManager.instance.tb_videoEvent.updateVideo(lastVideoEvent!!)
                }

            }else{
                val photoPath = "${com.boby.homecamera.constant.Constant.RECORD_FILE_DIR}${System.currentTimeMillis()}_msg4.jpeg"

                lastVideoEvent = VideoEvent(eventType = 4, startTime = startTime, endTime = startTime + PERSON_VISIBLE_TIME, capturePhoto = photoPath)
                val id = DBManager.instance.tb_videoEvent.insertVideoEvent(lastVideoEvent!!)
                savePhoto(photoPath)
                lastVideoEvent!!.id = id
                MainService.webSocketServer?.sendVideoEvent(lastVideoEvent!!.copy(id))
            }

        }else{
            //没有检测到人像
            if(lastVideoEvent != null){
                if(System.currentTimeMillis() > lastVideoEvent!!.endTime ){
                    lastVideoEvent = null
                }
            }
        }
    }

    fun release(){
        isStart = false
        detectPersonHandler?.removeCallbacksAndMessages(null)
        detectPersonHandler = null

    }
    private fun savePhoto(path:String){
        MainService.recordServer?.glInterface?.takePhoto(AppConfig.Record.CAPTURE_WIDTH/2,AppConfig.Record.CAPTURE_HEIGHT/2){
            try {
                BaseApplication.getWorkHandler()?.post {
                    FileUtil.saveBitmapToDir(it,null,path)
                }
            }catch (e:Exception){
                e.printStackTrace()
            }

        }
    }

}